package com.love.marriage.userMembershipInfo.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.love.marriage.common.enums.MembershipType;
import com.love.marriage.common.enums.ResultEnum;
import com.love.marriage.common.exceptions.UserException;
import com.love.marriage.identityVerification.vo.IdentityVerificationVo;
import com.love.marriage.membershipConfiguration.service.MembershipConfigurationService;
import com.love.marriage.membershipConfiguration.vo.MembershipConfigurationVo;
import com.love.marriage.orderInfo.vo.OrderInfoVo;
import com.love.marriage.userInfo.vo.UserInfoVo;
import com.love.marriage.userMembershipHistory.service.UserMembershipHistoryService;
import com.love.marriage.userMembershipHistory.vo.UserMembershipHistoryVo;
import com.love.marriage.userMembershipInfo.entity.UserMembershipInfo;
import com.love.marriage.userMembershipInfo.mapper.UserMembershipInfoMapper;
import com.love.marriage.userMembershipInfo.service.UserMemberPrivilegeService;
import com.love.marriage.userMembershipInfo.service.UserMembershipInfoService;
import com.love.marriage.userMembershipInfo.vo.UserMembershipInfoExportVo;
import com.love.marriage.userMembershipInfo.vo.UserMembershipInfoPageVo;
import com.love.marriage.userMembershipInfo.vo.UserMembershipInfoVo;
import com.love.marriage.userMembershipRewardInfo.service.UserMembershipRewardInfoService;
import com.love.marriage.userProfileInfo.vo.UserProfileInfoVo;
import com.love.marriage.utils.StringUtils;
import lombok.RequiredArgsConstructor;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * description:  用户会员表服务实现类
 * author:       mybatisPlus
 * createDate:   2024-10-17 07:29:59
 * version:      1.0.0
 */
@Service
@RequiredArgsConstructor
public class UserMembershipInfoServiceImp extends ServiceImpl<UserMembershipInfoMapper, UserMembershipInfo> implements UserMembershipInfoService {

    private final UserMembershipInfoMapper userMembershipInfoMapper;

    private final MembershipConfigurationService membershipConfigurationService;

    private final UserMemberPrivilegeService userMemberPrivilegeService;

    private final UserMembershipRewardInfoService userMembershipRewardInfoService;

    private final UserMembershipHistoryService userMembershipHistoryService;

    @Override
    public Page<UserMembershipInfoPageVo> getPage(Long pageNum, Long pageSize, UserMembershipInfoVo userMembershipInfoVo) {
        Page<UserMembershipInfoVo> page = new Page<>(pageNum == null ? 1 : pageNum, pageSize == null ? 10 : pageSize);
        return userMembershipInfoMapper.getPage(page, userMembershipInfoVo);
    }

    @Override
    public List<UserMembershipInfoPageVo> getList(UserMembershipInfoVo userMembershipInfoVo) {
        // 如果没有传递查询条件或者明确指定了memberStatus为true，则查询有效会员
        // 否则按照传入的条件进行查询
        if (userMembershipInfoVo == null) {
            userMembershipInfoVo = new UserMembershipInfoVo();
            userMembershipInfoVo.setMemberStatus(true); // 默认查询有效会员
        } else if (userMembershipInfoVo.getMemberStatus() == null) {
            // 如果没有明确指定会员状态，则不添加默认的有效会员限制，让用户自由查询
            // 这样可以支持导出功能的灵活筛选
        }

        return userMembershipInfoMapper.getList(userMembershipInfoVo);
    }

    @Override
    public UserMembershipInfoVo queryUserMembershipInfo(Long id) {
        return userMembershipInfoMapper.queryUserMembershipInfo(id);
    }

    @Override
    public UserMembershipInfoVo queryUserMembershipInfoByUserId(Long userId) {
        return userMembershipInfoMapper.queryUserMembershipInfoByUserId(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserMembershipInfoVo membershipBack(OrderInfoVo orderInfoVo) throws Exception {
        // 查询当前用户会员状态
        UserMembershipInfoVo dbMember = queryUserMembershipInfoByUserId(orderInfoVo.getUserId());
        // 查询会员配置信息
        BigDecimal payAmount = orderInfoVo.getTotalAmount();
        MembershipConfigurationVo membershipConfigurationVo = membershipConfigurationService.queryMembershipConfiguration(orderInfoVo.getBusinessId());
        MembershipType membershipType = MembershipType.getMembershipTypeByCode(membershipConfigurationVo.getMembership());
        if (membershipType == null) {
            throw new UserException(ResultEnum.MEMBER_TYPE_NO_EXISTS);
        }
        // 获取当前时间
        LocalDate startTime = LocalDate.now();
        int operateType;
        LocalDate endTime = membershipType.calculateStartTime(startTime);
        if (dbMember == null) {
            // 如果是不是会员，直接新增
            UserMembershipInfoVo userMembershipInfoVo = new UserMembershipInfoVo();
            userMembershipInfoVo.setMembershipId(orderInfoVo.getBusinessId());
            userMembershipInfoVo.setUserId(orderInfoVo.getUserId());
            // 获取会员时长
            userMembershipInfoVo.setStartTime(startTime.atStartOfDay());
            userMembershipInfoVo.setEndTime(endTime.minusDays(1).atStartOfDay());
            userMembershipInfoVo.setMembershipId(membershipConfigurationVo.getId());
            dbMember = addUserMembershipInfo(userMembershipInfoVo);
            operateType = 0;
        } else {
            // 如果是会员，当前时间和会员开始时间、结束时间比较
            if (LocalDate.now().atStartOfDay().isBefore(dbMember.getEndTime())) {
                //如果当前时间在结束时间之前，直接在结束时间 + 会员对应的时长
                endTime = membershipType.calculateStartTime(dbMember.getEndTime().toLocalDate());
                dbMember.setEndTime(endTime.atStartOfDay());
            } else {
                // 如果当前时间在结束时间之后，直接修改开始结束时间
                // 获取会员时长
                endTime = membershipType.calculateStartTime(startTime);
                dbMember.setStartTime(startTime.atStartOfDay());
                dbMember.setEndTime(endTime.minusDays(1).atStartOfDay());
            }
            operateType = 1;
            dbMember.setMembershipId(membershipConfigurationVo.getId());
            updateUserMembershipInfo(dbMember);
        }
        // 添加会员后，将数据插入到会员历史记录表中
        UserMembershipHistoryVo userMembershipHistoryInfoVo = new UserMembershipHistoryVo()
                .setOperationType(operateType)
                .setUserId(dbMember.getUserId())
                .setMembershipId(dbMember.getMembershipId())
                .setStartTime(LocalDate.now().atStartOfDay())
                .setEndTime(endTime.minusDays(1).atStartOfDay())
                .setOriginalId(dbMember.getId());
        userMembershipHistoryService.addUserMembershipHistory(userMembershipHistoryInfoVo);
        // 如果 会员是悬赏金额则添加数据
        if ("four_year".equals(membershipConfigurationVo.getMembership())) {
            userMembershipRewardInfoService.userMembershipRewardInfo(membershipConfigurationVo,
                    orderInfoVo.getUserId(), orderInfoVo.getBusinessId());
        }
        // 添加会员权益
        userMemberPrivilegeService.addMemberPrivilege(dbMember.getUserId());
        return dbMember;
    }

    @Override
    public UserMembershipInfoVo addUserMembershipInfo(UserMembershipInfoVo userMembershipInfoVo) {
        UserMembershipInfo userMembershipInfo = new UserMembershipInfo();
        BeanUtils.copyProperties(userMembershipInfoVo, userMembershipInfo);
        userMembershipInfoMapper.insert(userMembershipInfo);
        UserMembershipInfoVo res = new UserMembershipInfoVo();
        BeanUtils.copyProperties(userMembershipInfo, res);
        return res;
    }

    @Override
    public UserMembershipInfoVo addUserMembershipInfoAdmin(UserMembershipInfoVo userMembershipInfoVo) {
        // 查询当前用户会员状态
        UserMembershipInfoVo dbMember = queryUserMembershipInfoByUserId(userMembershipInfoVo.getUserId());
        MembershipConfigurationVo membershipConfigurationVo = membershipConfigurationService.queryMembershipConfiguration(userMembershipInfoVo.getMembershipId());
        MembershipType membershipType = MembershipType.getMembershipTypeByCode(membershipConfigurationVo.getMembership());
        if (membershipType == null) {
            throw new UserException(ResultEnum.MEMBER_TYPE_NO_EXISTS);
        }
        // 获取当前时间
        LocalDate startTime = LocalDate.now();
        if (dbMember == null) {
            // 如果是不是会员，直接新增
            // 获取会员时长
            LocalDate endTime = membershipType.calculateStartTime(startTime);
            userMembershipInfoVo.setStartTime(startTime.atStartOfDay());
            userMembershipInfoVo.setEndTime(endTime.minusDays(1).atStartOfDay());
            dbMember = addUserMembershipInfo(userMembershipInfoVo);
        } else {
            // 如果是会员，当前时间和会员开始时间、结束时间比较
            if (LocalDate.now().atStartOfDay().isBefore(dbMember.getEndTime())) {
                //如果当前时间在结束时间之前，直接在结束时间 + 会员对应的时长
                LocalDate endTime = membershipType.calculateStartTime(dbMember.getEndTime().toLocalDate());
                dbMember.setEndTime(endTime.atStartOfDay());
            } else {
                // 如果当前时间在结束时间之后，直接修改开始结束时间
                // 获取会员时长
                LocalDate endTime = membershipType.calculateStartTime(startTime);
                dbMember.setStartTime(startTime.atStartOfDay());
                dbMember.setEndTime(endTime.minusDays(1).atStartOfDay());
            }
            updateUserMembershipInfo(dbMember);
        }
        // 如果 会员是悬赏金额则添加数据
        if ("four_year".equals(membershipConfigurationVo.getMembership())) {
            userMembershipRewardInfoService.userMembershipRewardInfo(membershipConfigurationVo,
                    userMembershipInfoVo.getUserId(), membershipConfigurationVo.getId());
        }
        return dbMember;
    }

    @Override
    public UserMembershipInfoVo updateUserMembershipInfo(UserMembershipInfoVo userMembershipInfoVo) {
        UserMembershipInfo userMembershipInfo = new UserMembershipInfo();
        BeanUtils.copyProperties(userMembershipInfoVo, userMembershipInfo);
        userMembershipInfoMapper.updateById(userMembershipInfo);
        return userMembershipInfoVo;
    }

    @Override
    public Boolean deleteUserMembershipInfo(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return true;
        }
        List<String> idArr = Arrays.asList(ids.split(","));
        userMembershipInfoMapper.deleteBatchIds(idArr);
        return true;
    }

    @Override
    public void exportUserMembershipInfo(UserMembershipInfoVo userMembershipInfoVo, HttpServletResponse response) throws Exception {
        List<UserMembershipInfoPageVo> list = getList(userMembershipInfoVo);
        List<UserMembershipInfoExportVo> exportList = list.stream().map(item -> {
            UserMembershipInfoExportVo exportVo = new UserMembershipInfoExportVo();

            // 基本会员信息
            exportVo.setStartTime(item.getStartTime());
            exportVo.setEndTime(item.getEndTime());
            exportVo.setMembershipName(item.getMembershipName());

            // 会员状态判断
            if (item.getEndTime() != null && LocalDateTime.now().isBefore(item.getEndTime())) {
                exportVo.setMemberStatusName("有效");
            } else {
                exportVo.setMemberStatusName("已过期");
            }

            if (item.getUserInfoVo() != null) {
                UserInfoVo userInfoVo = item.getUserInfoVo();
                exportVo.setCode(userInfoVo.getCode());
            }
            if (item.getUserProfileInfoVo() != null) {
                UserProfileInfoVo userProfile = item.getUserProfileInfoVo();
                exportVo.setNickname(userProfile.getNickname());
                // 设置性别
                if ("0".equals(userProfile.getGender())) {
                    exportVo.setGenderName("男");
                } else if ("1".equals(userProfile.getGender())) {
                    exportVo.setGenderName("女");
                }

                // 计算年龄
                if (userProfile.getBirthYearMonth() != null) {
                    int age = Period.between(userProfile.getBirthYearMonth(), LocalDate.now()).getYears();
                    exportVo.setAge(age);
                }

                // 身高体重
                exportVo.setHeight(userProfile.getHeight());
                exportVo.setWeight(userProfile.getWeight());

                // 地域信息
                String region = "";
                if (userProfile.getProvinceName() != null) {
                    region += userProfile.getProvinceName();
                }
                if (userProfile.getCityName() != null) {
                    if (!region.isEmpty()) region += "/";
                    region += userProfile.getCityName();
                }
                if (userProfile.getDistrictName() != null) {
                    if (!region.isEmpty()) region += "/";
                    region += userProfile.getDistrictName();
                }
                exportVo.setRegion(region);

                // 其他信息
                exportVo.setIncomeStatusName(userProfile.getIncomeStatusName());
                exportVo.setPhone(userProfile.getContactPhone());
                
                // 新增字段
                exportVo.setProfessionName(userProfile.getProfessionName());
                exportVo.setMaritalStatusName(userProfile.getMaritalStatusName());
                exportVo.setCarHouseStatusName(userProfile.getCarHouseStatusName());
            }


            if (item.getIdentityVerificationVo() != null) {
                IdentityVerificationVo identityVerificationVo = item.getIdentityVerificationVo();
                exportVo.setIdentityName(identityVerificationVo.getName());
                exportVo.setIdentityIdCardNumber(identityVerificationVo.getIdCardNumber());
            }

            exportVo.setProcessTime(item.getOperateTime());
            return exportVo;
        }).collect(Collectors.toList());

        exportUserMembershipData(exportList, response);
    }

    private void exportUserMembershipData(List<UserMembershipInfoExportVo> exportList, HttpServletResponse response) throws Exception {
        // 设置导出参数
        ExportParams exportParams = new ExportParams("会员信息", "会员信息");

        // 生成 Excel
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, UserMembershipInfoExportVo.class, exportList);

        // 设置响应头
        response.setContentType("application/vnd.ms-excel; charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; filename=member_info.xlsx");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");

        // 将 Excel 写入响应输出流并刷新缓冲区
        workbook.write(response.getOutputStream());
        response.flushBuffer();
        workbook.close();
    }
}
